#include <stack>
#include <cstring>
#include "vl_props.h"
#include "vl_prop_file_writer.h"
#include "vl_prop_file_reader.h"

using namespace VL;

namespace VL {

#define _VL_ERASE_FRONT_SPACE(begin, end) \
while(begin < end && (line.at(begin) == ' ' || line.at(begin) == '\t')) { \
	begin ++; \
}

#define _VL_ERASE_BACK_SPACE(begin, end) \
while(end < begin && (line.at(begin - 1) == ' ' || line.at(begin - 1) == '\t')) { \
	begin --; \
}

#define _VL_FIND_COLON \
colonIndex = line.find(':', begin); \
if(colonIndex == begin) { \
	throw VLPropExcetion(VL_PROP_ERROR_READ_COLON, "format error: %s", line.c_str()); \
}

#define _VL_MUST_FIND_COLON \
_VL_FIND_COLON \
if(colonIndex == std::string::npos) { \
	throw VLPropExcetion(VL_PROP_ERROR_READ_NOT_FOUND_COLON, "format error: %s", line.c_str()); \
}

enum class _ControlMode {
	None,
	Ignore,
	If,
	Elseif
};

enum class _ContinueMode {
	None,
	IfHit
};

enum class _CombineStatus {
	Completed,
	Waiting,
	Pending,
};

struct VLPropRefCore {
	VLPropRefCore(VLProp* ref, bool top): _ref(ref), _ref2(nullptr), top(top) {}
	VLPropRefCore(const std::shared_ptr<VLProp>& ref, bool top): _ref(nullptr), _ref2(ref), top(top) {}
	VLProp* ref() { 
		if(this->_ref == nullptr) return this->_ref2.get();
		else return this->_ref;
	}
	VLProp* _ref;
	std::shared_ptr<VLProp> _ref2;
	bool top;
	_CombineStatus combineStatus = _CombineStatus::Completed;
	std::shared_ptr<std::set<std::string>> templateSet;
	std::shared_ptr<std::set<std::string>> uniqueTemplateSet;
};

struct VLPropRef {
	VLPropRef(const VLPropRef* parent, VLProp* ref, uint32_t id, bool top = false): 
		core(new VLPropRefCore(ref, top)), id(id), isTemplate(parent == nullptr ? false : parent->isTemplate) {}
	VLPropRef(const VLPropRef* parent, const std::shared_ptr<VLProp>& ref, uint32_t id, bool top = false): 
		core(new VLPropRefCore(ref, top)), id(id), isTemplate(parent == nullptr ? false : parent->isTemplate) {}
	VLPropRef(const VLPropRef* parent, const VLPropRef& ref, uint32_t id): 
		core(ref.core), id(id), isTemplate(parent == nullptr ? false : parent->isTemplate) {}

	VLPropRefCore* operator ->() {
		return this->core.get();
	}

	uint32_t id;
	std::shared_ptr<VLPropRefCore> core;
	bool isTemplate;
	_ControlMode controlMode = _ControlMode::None;
	_ContinueMode continueMode = _ContinueMode::None;
};

struct VLPropRefEqual {
	bool operator()(const VLPropRef& ref1, const VLPropRef& ref2) const {
		return ref1.id != ref2.id;
	}
};

bool _judgeCondition(const std::string& line, const std::set<std::string>& featureSet) {
	size_t begin = 0, end = line.size(), index = 0;
	if(end == 0) {
		return false;
	}
	_VL_ERASE_FRONT_SPACE(begin, end);
	if(begin == end) {
		return false;
	}
	_VL_ERASE_BACK_SPACE(end, begin);
	if(begin == end) {
		return false;
	}
	return featureSet.find(line.substr(begin, end)) != featureSet.end();
}

void _analyzeConstants(const std::string& line, std::string& str, const std::map<std::string, std::string>& constants) {
	str.clear();
	size_t begin = 0, index = 0, open = 0, close = 0, size = line.size();
	bool isConcated = false;
	std::string constantValue = "";
	while(index < size) {
		index = line.find('$', index);
		if(index == std::string::npos) {
			break;
		}
		if(index != 0 && line.at(index - 1) == '\\') {
			index = index + 1;
			continue;
		}

		if(index + 1 < size && line.at(index + 1) == '{') {
			open = index + 2;
			close = line.find('}', open);
			if(close == std::string::npos) {
				break;
			}
			constantValue.clear();
			if(close - open > 1) {
				auto iter = constants.find(line.substr(open, close - open));
				if(iter != constants.end()) {
					constantValue = iter->second;
				}
			}
			if(begin == index) {
				str += constantValue;
			} else {
				str = line.substr(begin, index) + constantValue;
			}
			isConcated = true;
			
			index = close + 1;
			begin = index;
		} else {
			index = index + 1;
		}
	}
	if(isConcated) {
		if(begin != size) {
			// 拼接剩余部分
			str += line.substr(begin);
		}
	} else {
		str = line;
	}
}

void _analyzeNodeProp(const std::string& line, VLProp& prop, const std::map<std::string, std::string>& constants) {
	// 处理常量
	std::string str = "";
	_analyzeConstants(line, str, constants);
	str.erase(0, str.find_first_not_of(' '));
	str.erase(str.find_last_not_of(' ') + 1);
	size_t size = str.size();

	// 值模式
	// 0 - 未知
	// 1 - 字符串
	// 2 - 数字
	// 3 - 小数
	// 4 - 布尔值 true
	// 5 - 布尔值 false
	char valueMode = 0;
	bool isNegative = false;
	int64_t  n1 = 0;
	uint64_t n2 = 0;
	double   n3 = 0;

	for(size_t i = 0 ; i < size ; i ++) {
		char c = str.at(i);
		if(c >= '0' && c <= '9') {
			if(valueMode == 3) {
				continue;
			}
			uint8_t number = c - '0';
			if(valueMode == 0) {
				valueMode = 2;
				if(isNegative) {
					n1 = ((int64_t) number) * -1;
				} else {
					n2 = number;
				}
				continue;
			}
			else if(valueMode == 2) {
				if(isNegative) {
					if(INT64_MIN / n1 < 10) {
						valueMode = 1;
						break;
					}
					n1 = n1 * 10 - number;
				} else {
					if(UINT64_MAX / n2 < 10) {
						valueMode = 1;
						break;
					}
					n2 = n2 * 10 + number;
				}
				continue;
			}
		} else if(c == '-' && valueMode == 0) {
			isNegative = true;
			continue;
		} else if(c == '.' && valueMode == 2) {
			valueMode = 3;
			continue;
		}

		valueMode = 1;
		break;
	}

	if(valueMode == 0) {
		valueMode = 1;
	} else if(valueMode == 1) {
		if(size == 4 && ::strcmp("true", str.c_str()) == 0) {
			valueMode = 4;
		}
		if(size == 5 && ::strcmp("false", str.c_str()) == 0) {
			valueMode = 5;
		}
	} else if(valueMode == 3) {
		try {
			n3 = std::stod(str);
		} catch(...) {
			valueMode = 1;
		}
	}

	switch(valueMode) {
		case 1:
			prop = str;
			break;
		case 2:
			if(isNegative) {
				if(n1 >= INT8_MIN) {
					prop = (int8_t) n1;
				} else if(n1 >= INT16_MIN) {
					prop = (int16_t) n1;
				} else if(n1 >= INT32_MIN) {
					prop = (int32_t) n1;
				} else {
					prop = (int64_t) n1;
				}
			} else {
				if(n2 <= UINT8_MAX) {
					prop = (uint8_t) n2;
				} else if(n2 >= UINT16_MAX) {
					prop = (uint16_t) n2;
				} else if(n2 >= UINT32_MAX) {
					prop = (uint32_t) n2;
				} else {
					prop = (uint64_t) n2;
				}
			}
			break;
		case 3:
			prop = n3;
			break;
		case 4:
			prop = true;
			break;
		case 5:
			prop = false;
			break;
		default: break;
	}
}


void _combineTemplateProp (
	VLPropRef& ref,
	const std::map<std::string, VLPropRef> & templateMap
) {
	if(ref->combineStatus == _CombineStatus::Completed) {
		return;
	}
	if(ref->combineStatus == _CombineStatus::Pending) {
		throw VLPropExcetion(VL_PROP_ERROR_READ_TEMPLATE_LOOP, "combine template loop");
	}
	ref->combineStatus = _CombineStatus::Pending;

	if(ref->templateSet.get() != nullptr) {
		if(ref->uniqueTemplateSet.get() == nullptr) {
			ref->uniqueTemplateSet.reset(new std::set<std::string>);
		}
		auto uniqueSet = ref->uniqueTemplateSet;
		for(auto templateNameIter = ref->templateSet->begin() ; templateNameIter != ref->templateSet->end() ; templateNameIter ++) {
			// 寻找模板
			auto & templateName = *templateNameIter;
			if(uniqueSet->find(templateName) != uniqueSet->end()) {
				// 已经合并完毕, 不做重复合并
				continue;
			}
			auto templateIter = templateMap.find(templateName);
			if(templateIter != templateMap.end()) {
				auto templateRef = templateIter->second;
				_combineTemplateProp(templateRef, templateMap);
				if(templateRef->uniqueTemplateSet.get() != nullptr) {
					// 将模板中嵌套模板也作为已引入模板
					uniqueSet->insert(templateRef->uniqueTemplateSet->begin(), templateRef->uniqueTemplateSet->end());
				}
				// 找到模板
				// 进行合并
				auto & templateProp = (*templateRef->ref());
				if(!ref->ref()->combine(templateProp)) {
					// 合并失败, 抛出异常
					throw VLPropExcetion(VL_PROP_ERROR_READ_TEMPLATE_COMBINE, "cannot combine template %s", templateName.c_str());
				}
			}
			uniqueSet->emplace(templateName);
		}
	}
	ref->combineStatus = _CombineStatus::Completed;
}

};


void VLProp::readVLC(VLPropReader& reader, VLProp& prop) {
	prop.reset();
	auto type = (VLPropType) (reader.read() & 0xFF);
	prop.type = type;
	switch(type) {
		case VLPropType::Node:
			prop._readNodeVLC(reader);
			break;
		case VLPropType::Array:
			prop._readArrayVLC(reader);
			break;
		case VLPropType::Map:
			prop._readMapVLC(reader);
			break;
		case VLPropType::Empty:
			prop._readEmptyVLC(reader);
			break;
	}
}

std::shared_ptr<VLPropReader> _newReader(const std::string& url) {
	return std::make_shared<VLPropFileReader>(url);
}

void VLProp::readVLP(VLPropReader& reader, VLProp& prop, const std::map<std::string, std::string>& constants, const std::set<std::string>& featureSet) {
	prop.reset();
	// 引用数组
	std::stack<VLPropRef> refStack;
	// 待模板匹配集合
	std::set<VLPropRef, VLPropRefEqual> templateMarchSet;
	// 模板映射表
	std::map<std::string, VLPropRef> templateMap;
	// 临时注释列表
	std::vector<std::string> commentList;
	// 临时模板匹配列表
	size_t begin = 0, end = 0;
	std::string line;
	// curLayer 是当前解析出来的层级, indexLayer 表示当前属性对象, 子属性的层级, 也就是可接受最大的层级
	// 比如 indexLayer = 0 表示函数参数属性对象的子属性层级
	size_t indexLayer = 0, curLayer = 0;
	// 字符遍历下标
	size_t index = 0;
	// 下标距离长度
	size_t dist = 0;
	// 冒号下标
	size_t colonIndex = std::string::npos;
	// Key 值范围下标
	size_t keyBegin = 0, keyEnd = 0;
	// 判断是否为数组元素
	static const char MAP_ITEM = 0;
	static const char ARRAY_ITEM = 1;
	static const char TEMPLATE_ITEM = 2;
	char itemType = MAP_ITEM;
	// 嵌套数组倾向
	// 0 - 无倾向
	// 1 - 倾向 array
	// 2 - 倾向 map
	static const char NO_PREFER = 0;
	static const char PERFER_ARRAY = 1;
	static const char PERFER_MAP = 2;
	char arrayNestPrefer = NO_PREFER;

	// 临时属性
	uint32_t refId = 0;
	VLProp tempProp;
	std::string multiLine = "";
	VLPropRef curRef(nullptr, &prop, refId++, true);

	// reader
	VLPropReader* currentReader = &reader;
	std::stack<std::shared_ptr<VLPropReader>> readerStack;

	// 当前属性引用
	ANALYZE_LOOP:
	while(!currentReader->isEof()) {
		currentReader->readLine(line);
		if(line.empty()) {
			goto CONTROL_NEXT;
		}
		RELOOP:
		// 重置当前层级
		curLayer = 0;

		// 去掉左右空格
		begin = line.find_first_not_of(' ');
		if(begin == std::string::npos) {
			if(!multiLine.empty()) {
				line = multiLine;
				multiLine = "";
				goto RELOOP;
			}
			goto CONTROL_NEXT;
		}
		end = line.find_last_not_of(' ') + 1;
		_VL_ERASE_BACK_SPACE(end, begin)
		if(begin == end) {
			if(!multiLine.empty()) {
				line = multiLine;
				multiLine = "";
				goto RELOOP;
			}
			goto CONTROL_NEXT;
		}

		// 判断是否为多行属性
		if(line.at(end - 1) == '\\') {
			// 是多行属性, 合并多行为一行, 继续遍历
			if(multiLine.empty()) {
				// 首行保留缩进
				multiLine = line.substr(begin, end - 1);
			} else {
				_VL_ERASE_FRONT_SPACE(begin, end)
				multiLine += line.substr(begin, end - 1);
			}
			goto CONTROL_NEXT;
		} else if(!multiLine.empty()) {
			// 不是多行属性, 但是之前存在多行属性, 合并到多行中处理
			_VL_ERASE_FRONT_SPACE(begin, end)
			line = multiLine + line.substr(begin, end);
			multiLine = "";
			goto RELOOP;
		}
		
		// 计算缩进, 表示层级
		// 依据水平制表符作为缩进依据
		// 每存在一个水平制表符 \t 表示层级 + 1
		// 计算之后抹去水平制表符
		while(begin < end) {
			if(line.at(begin) == '\t') {
				curLayer ++;
				begin ++;
			} else {
				break;
			}
		}
		// 去掉缩进后, 再抹除一遍空格
		_VL_ERASE_FRONT_SPACE(begin, end)
		// 如果处理之后为空, 不做处理
		if(begin == end) {
			goto CONTROL_NEXT;
		}

		// 根据缩进, 寻找上级容器属性
		if(curLayer > indexLayer) {
			if(curRef.controlMode == _ControlMode::Ignore) {
				// 忽略
				goto CONTROL_NEXT;
			}
			// 缩进异常, 抛出
			throw VLPropExcetion(VL_PROP_ERROR_READ_INDENT, "format error: %s, curLayer: %d, indexLayer: %d", line.c_str(), curLayer, indexLayer);
		}

		// 首字符是 # 表示注释
		if(line.at(begin) == '#') {
			begin ++;
			if(curRef.controlMode != _ControlMode::Ignore) {
				commentList.push_back(line.substr(begin, end - begin));
			}
			goto CONTROL_NEXT;
		}

		if(curLayer < indexLayer) {
			// 层级比当前层级小, 表示应回退到上层
			while(indexLayer != curLayer) {
				curRef = refStack.top();
				refStack.pop();
				indexLayer --;
			}
		} else if(curRef.controlMode == _ControlMode::Ignore) {
			goto CONTROL_NEXT;
		}
		// 分析行内内容
		// 分析首个字符, 判断是否为宏定义
		switch(line.at(begin)) {
			case '@':
				dist = end - begin;
				// 模板定义、控制语句、模板引用都是以 @ 开始
				// 匹配 @if [FEATURE] 、 @elseif [FEATURE] 、 @else
				if(dist >= 3) {
					// 匹配 @if
					if(line.compare(begin + 1, 2, "if") == 0) {
						// 已匹配 @if
						if(curRef.controlMode != _ControlMode::None && curRef.controlMode != _ControlMode::If && curRef.controlMode != _ControlMode::Elseif) {
							throw VLPropExcetion(VL_PROP_ERROR_READ_CONTROL, "format error: %s", line.c_str());
						}
						begin += 3;
						// 判断 if 条件
						curRef.controlMode = _ControlMode::If;
						curRef.continueMode = _ContinueMode::None;
						// 造一个伪 ref
						refStack.push(curRef);
						curRef = VLPropRef(&curRef, curRef, refId++);
						commentList.clear();
						indexLayer ++;
						if(end == begin || !_judgeCondition(line.substr(begin), featureSet)) {
							curRef.controlMode = _ControlMode::Ignore;
						} else {
							refStack.top().continueMode = _ContinueMode::IfHit;
						}
						goto CONTROL_NEXT;
					}
				}
				if(dist >= 7) {
					// 匹配 @elseif
					if(line.compare(begin + 1, 6, "elseif") == 0) {
						// 已匹配 @elseif, 前提条件, 必须接在 @if 或者 @elseif 下面
						if(curRef.controlMode != _ControlMode::If && curRef.controlMode != _ControlMode::Elseif) {
							throw VLPropExcetion(VL_PROP_ERROR_READ_CONTROL, "format error: %s", line.c_str());
						}
						begin += 7;
						curRef.controlMode = _ControlMode::Elseif;
						// 造一个伪 ref
						refStack.push(curRef);
						curRef = VLPropRef(&curRef, curRef, refId++);
						commentList.clear();
						indexLayer ++;
						if(end == begin || refStack.top().continueMode == _ContinueMode::IfHit || !_judgeCondition(line.substr(begin), featureSet)) {
							curRef.controlMode = _ControlMode::Ignore;
						} else {
							refStack.top().continueMode = _ContinueMode::IfHit;
						}
						goto CONTROL_NEXT;
					}
				}
				if(dist >= 5) {
					// 匹配 @else
					if(line.compare(begin + 1, 4, "else") == 0) {
						// 已匹配 @else, 前提条件, 必须接在 @if 或者 @elseif 下面
						if(curRef.controlMode != _ControlMode::If && curRef.controlMode != _ControlMode::Elseif) {
							throw VLPropExcetion(VL_PROP_ERROR_READ_CONTROL, "format error: %s", line.c_str());
						}
						begin += 5;
						curRef.controlMode = _ControlMode::None;
						// 造一个伪 ref
						refStack.push(curRef);
						curRef = VLPropRef(&curRef, curRef, refId++);
						commentList.clear();
						indexLayer ++;
						if(end != begin || refStack.top().continueMode == _ContinueMode::IfHit) {
							curRef.controlMode = _ControlMode::Ignore;
						}
						goto CONTROL_NEXT;
					}
				}

				// 匹配 @error [MSG]
				if(dist >= 6) {
					if(line.compare(begin + 1, 5, "error") == 0) {
						// 匹配 @error, 直接抛出异常
						begin += 6;
						_VL_ERASE_FRONT_SPACE(begin, end)
						if(begin == end) {
							throw VLPropExcetion(VL_PROP_ERROR_READ_ERROR, "analyze error, no reason");
						} else {
							throw VLPropExcetion(VL_PROP_ERROR_READ_ERROR, "analyze error: %s", line.substr(begin, end - begin).c_str());
						}
					}
				}

				// 匹配 @import
				if(dist >= 7) {
					if(line.compare(begin + 1, 6, "import") == 0) {
						// 匹配 @import 加载绝对路径
						if(!curRef->top) {
							throw VLPropExcetion(VL_PROP_ERROR_READ_IMPORT, "@import must at root node: %s", line.c_str());
						}
						begin += 7;
						curRef.continueMode = _ContinueMode::None;

						_VL_ERASE_FRONT_SPACE(begin, end)
						// 生成新的 Reader, 并入到当前文件中
						readerStack.push(_newReader(line.substr(begin)));
						currentReader = readerStack.top().get();
						goto CONTROL_NEXT;
					}
				}
				
				// 判断是否为模板引用
				if(dist > 3) {
					if(line.at(begin + 1) == '{' && line.at(end - 1) == '}') {
						// 确认为模板引入
						// 注意, 根属性无法引入模板, 直接忽略
						curRef.continueMode = _ContinueMode::None;
						if(curRef->top) {
							goto CONTROL_NEXT;
						}
						if(curRef->templateSet.get() == nullptr) {
							curRef->templateSet = std::make_shared<std::set<std::string>>();
						}
						curRef->templateSet->insert(line.substr(begin + 2, end - 1 - begin - 2));
						curRef->combineStatus = _CombineStatus::Waiting;
						if(!curRef.isTemplate) {
							templateMarchSet.insert(curRef);
						}
						goto CONTROL_NEXT;
					}
				}

				if(end - begin > 2) {
					_VL_FIND_COLON
					if(colonIndex != std::string::npos) {
						// 确认为模板定义
						if(!curRef->top) {
							throw VLPropExcetion(VL_PROP_ERROR_READ_TEMPLATE_DEF, "format error: %s", line.c_str());
						}
						itemType = TEMPLATE_ITEM;
						keyBegin = begin + 1;
						keyEnd = colonIndex;
						_VL_ERASE_BACK_SPACE(keyEnd, keyBegin)
						begin = colonIndex + 1;
						break;
					}
				}
				goto DEFAULT;
			case '-':
				// 数组元素以 - 开始
				// 抹除掉符号
				itemType = ARRAY_ITEM;
				begin ++;
				_VL_ERASE_FRONT_SPACE(begin, end)
				// 尝试寻找冒号, 匹配 [] {}
				_VL_FIND_COLON
				if(colonIndex != std::string::npos) {
					// 找到冒号, 尝试匹配 [] {}
					keyBegin = begin;
					keyEnd = colonIndex;
					_VL_ERASE_BACK_SPACE(keyEnd, keyBegin)
					if(keyEnd - keyBegin == 2) {
						if(line.at(keyBegin) == '{' && line.at(keyBegin + 1) == '}') {
							// array 内嵌套 map
							arrayNestPrefer = PERFER_MAP;
							begin = colonIndex + 1;
						} else if(line.at(keyBegin) == '[' && line.at(keyBegin + 1) == ']') {
							// array 内嵌套 array
							arrayNestPrefer = PERFER_ARRAY;
							begin = colonIndex + 1;
						}
					}
				}
				break;
			DEFAULT:
			default:
				// 常规映射表子属性元素
				// 寻找冒号下标
				_VL_MUST_FIND_COLON
				keyBegin = begin;
				keyEnd = colonIndex;
				_VL_ERASE_BACK_SPACE(keyEnd, keyBegin)
				if(begin == keyEnd) {
					throw VLPropExcetion(VL_PROP_ERROR_READ_COLON, "format error: %s", line.c_str());
				}
				begin = colonIndex + 1;
				break;
		}

		// 判断父级容器是否满足要求
		if(itemType == ARRAY_ITEM && !curRef->ref()->isArray() && !curRef->ref()->isEmpty()) {
			throw VLPropExcetion (VL_PROP_ERROR_READ_NOT_MATCH_ARRAY, "format error: %s", line.c_str());
		}
		if(itemType == MAP_ITEM && !curRef->ref()->isMap() && !curRef->ref()->isEmpty()) {
			throw VLPropExcetion(VL_PROP_ERROR_READ_NOT_MATCH_MAP, "format error: %s", line.c_str());
		}

		// 常规元素, 分析值
		if(begin == end) {
			// 无有效字符
			switch(itemType) {
				case ARRAY_ITEM: {
					// 如果是数组元素, 判断是否存在倾向, 如果不存在, 表示空数组元素, 直接跳过
					if(arrayNestPrefer == NO_PREFER) {
						goto NEXT;
					}
					switch(arrayNestPrefer) {
						case PERFER_ARRAY:
							refStack.push(curRef);
							// 实际添加属性
							curRef = VLPropRef(&curRef, &curRef->ref()->add(vArr()), refId++);
							curRef->ref()->addComments(commentList);
							commentList.clear();
							indexLayer ++;
							break;
						case PERFER_MAP:
							refStack.push(curRef);
							// 实际添加属性
							curRef = VLPropRef(&curRef, &curRef->ref()->add(vMap()), refId++);
							curRef->ref()->addComments(commentList);
							commentList.clear();
							indexLayer ++;
							break;
					}
					goto NEXT;
				}
				case MAP_ITEM: {
					refStack.push(curRef);
					// 实际添加属性
					curRef = VLPropRef(&curRef, &curRef->ref()->operator[](line.substr(keyBegin, keyEnd - keyBegin)), refId++);
					curRef->ref()->addComments(commentList);
					commentList.clear();
					indexLayer ++;
					goto NEXT;
				}
				case TEMPLATE_ITEM: {
					refStack.push(curRef);
					// 实际添加属性
					curRef = VLPropRef(&curRef, std::make_shared<VLProp>(), refId++);
					curRef.isTemplate = true;
					auto ret = templateMap.emplace(line.substr(keyBegin, keyEnd - keyBegin), curRef);
					if(!ret.second) {
						ret.first->second = curRef;
					}
					curRef->ref()->addComments(commentList);
					commentList.clear();
					indexLayer ++;
					goto NEXT;
				}
			}
		} else {
			_analyzeNodeProp(line.substr(begin, end - begin), tempProp, constants);
			tempProp.addComments(commentList);
			commentList.clear();
			switch(itemType) {
				case ARRAY_ITEM:
					curRef->ref()->add(tempProp);
					break;
				case MAP_ITEM:
					curRef->ref()->operator[](line.substr(keyBegin, keyEnd - keyBegin)) = tempProp;
					break;
				case TEMPLATE_ITEM: {
					auto templateRef = VLPropRef(&curRef, std::make_shared<VLProp>(tempProp), refId++);
					auto ret = templateMap.emplace(line.substr(keyBegin, keyEnd - keyBegin), templateRef);
					if(!ret.second) {
						ret.first->second = templateRef;
					}
					break;
				}
			}
			goto CONTROL_NEXT;
		}

		NEXT:
			curRef.controlMode = _ControlMode::None;
			curRef.continueMode = _ContinueMode::None;
		CONTROL_NEXT:
			colonIndex = std::string::npos;
			itemType = MAP_ITEM;
			arrayNestPrefer = NO_PREFER;
	}

	if(currentReader != &reader) {
		readerStack.pop();
		if(readerStack.empty()) {
			currentReader = &reader;
		} else {
			currentReader = readerStack.top().get();
		}
		goto ANALYZE_LOOP;
	}

	if(!multiLine.empty()) {
		throw VLPropExcetion(VL_PROP_ERROR_READ_CROSS_LINE, "invalid cross-line format");
	}

	// 解析完成后, 进行模板填充

	for(auto iter = templateMarchSet.begin() ; iter != templateMarchSet.end() ; iter ++) {
		auto ref = *iter;
		_combineTemplateProp(ref, templateMap);
	}
}


const void VLProp::writeVLC(const std::string& filePath) const {
	VLPropFileWriter writer(filePath);
	this->_writeVLC(writer);
}

const void VLProp::writeVLP(const std::string& filePath) const {
	VLPropFileWriter writer(filePath);
	this->_writeVLP(writer);
}

void VLProp::readVLC(const std::string& filePath, VLProp& prop) {
	VLPropFileReader reader(filePath);
	VLProp::readVLC(reader, prop);
}

void VLProp::readVLP(const std::string& filePath, VLProp& prop, const std::map<std::string, std::string>& constants, const std::set<std::string>& featureSet) {
	VLPropFileReader reader(filePath);
	VLProp::readVLP(reader, prop, constants, featureSet);
}